package pl.edu.pw.polygen.modeler.client.object;

import java.util.List;

import org.vaadin.gwtgraphics.client.Line;

import pl.edu.pw.polygen.modeler.client.Point;
import pl.edu.pw.polygen.modeler.client.graph.BaseModel;
import pl.edu.pw.polygen.modeler.client.object.listener.EmptyListener;
import pl.edu.pw.polygen.modeler.client.object.listener.IPolygenObjectListener;
import pl.edu.pw.polygen.modeler.client.object.listener.PolygenObjectListenerMultiton;
import pl.edu.pw.polygen.modeler.client.object.listener.SelectableSplainListener;
import pl.edu.pw.polygen.modeler.client.workspace.IWorkspace;
import pl.edu.pw.polygen.modeler.client.workspace.Workspace;

import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;

/**
 * @author borysfan
 * @version 0.0.1
 * SubSplain class representing one of the line in Splain Object
 */
public class SubSplain extends Line implements IPolygenObject{
	
	/**
	 * Coordinates of begin point of line
	 */
	private Point beginPoint;
	
	/**
	 * Coordinates of end point of line
	 */
	private Point endPoint;
	
	private IPolygenObjectListener polygenObjectListener;
	
	/**
	 * Handler to parent Splain object
	 */
	private Splain splain;
	
	/**
	 * Place where splain object will be holded
	 */
	private IWorkspace context;
	
	/*
	 * Handler to it self
	 */
	private SubSplain instance;
	
	
	public SubSplain(double x1, double y1, double x2, double y2,IWorkspace context) {
		super((int)Math.round(x1), (int)Math.round(y1), (int)Math.round(x2), (int)Math.round(y2));
		beginPoint = new Point(x1,y1);
		endPoint = new Point(x2,y2);
		this.context = context;
		this.instance = this;
	}
	
	public SubSplain(double x1, double y1, double x2, double y2,Splain parent) {
		super((int)Math.round(x1), (int)Math.round(y1), (int)Math.round(x2), (int)Math.round(y2));
		beginPoint = new Point(x1,y1);
		endPoint = new Point(x2,y2);
		this.splain = parent;
	}
		
	@Override
	public void initialize() {
		polygenObjectListener = new SelectableSplainListener();
		MouseActions mouseActions = new MouseActions();
		this.addMouseUpHandler(mouseActions);
		this.addMouseOverHandler(mouseActions);
		this.addMouseOutHandler(mouseActions);
		this.addMouseDownHandler(mouseActions);
	}

	@Override
	public void select() { 
		setStrokeColor(Splain.SELECTED_COLOR);
		setStrokeWidth(Splain.SELECTED_WIDTH);	
	}

	@Override
	public void unselect() {
		setStrokeColor(Splain.DEFAULT_COLOR);
		setStrokeWidth(Splain.DEFAULT_WIDTH);		
	}

	@Override
	public void hold() {
		setStrokeColor(Splain.HOVER_COLOR);
		setStrokeWidth(Splain.HOVER_WIDTH);
	}

	@Override
	public void drop() {
		setStrokeColor(Splain.DEFAULT_COLOR);
		setStrokeWidth(Splain.DEFAULT_WIDTH);	
	}

	@Override
	public void over() {
		setStrokeColor(Splain.HOVER_COLOR);
		setStrokeWidth(Splain.HOVER_WIDTH);
	}

	@Override
	public void out() {
		setStrokeColor(Splain.DEFAULT_COLOR);
		setStrokeWidth(Splain.DEFAULT_WIDTH);
	}
	
	@Override
	public boolean isHolded() {
		return splain.isHolded();
	}

	@Override
	public boolean isSelected() {
		return splain.isSelected();
	}

	@Override
	public IWorkspace getContext() {
		return context;
	}


	@Override
	public void draw(){
	}
	
	@Override
	public void setPolygenObjectListener(IPolygenObjectListener polygenObjectListener) {
		this.polygenObjectListener = polygenObjectListener;
	}

	public void add(){
		this.addToCanvas();
	}
	
	
	
	@Override
	public void merge(IPolygenObject sourceObject, IPolygenObject targetObject){
		// TODO Auto-generated method stub
		
	}

	@Override
	public void addToCanvas() {
		context.getCanvas().insert(this,0);
	}
	

	public void remove(){
		context.getCanvas().remove(this);
	}
	
	@Override
	public void setSelectable() {
		this.setPolygenObjectListener(PolygenObjectListenerMultiton.getInstance(SelectableSplainListener.class));
	}

	@Override
	public void setMergeable() {
		this.setPolygenObjectListener(PolygenObjectListenerMultiton.getInstance(EmptyListener.class));
	}

	@Override
	public void setLocked() {
		this.setPolygenObjectListener(PolygenObjectListenerMultiton.getInstance(EmptyListener.class));
	}
	
	
	
	@Override
	public void setContext(IWorkspace context) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void removeFromCanvas() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setPosition(int x, int y) {
		// TODO Auto-generated method stub
		
	}
	
	

	@Override
	public void setModel(BaseModel model) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public BaseModel getModel() {
		// TODO Auto-generated method stub
		return null;
	}
	
	

	@Override
	public List<IPolygenObject> getPolygenParents() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void addPolygenParent(IPolygenObject polygenParent) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void removePolygenParent(IPolygenObject polygenParent) {
		// TODO Auto-generated method stub
		
	}
	

	@Override
	public void showBoundary() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void hideBoundary() {
		// TODO Auto-generated method stub
		
	}

	public void moveTo(double dx,double dy){
		this.setX1(this.beginPoint.getX()+dx);
		this.setY1(this.beginPoint.getY()+dy);
		this.setX2(this.endPoint.getX()+dx);
		this.setY2(this.endPoint.getY()+dy);
	}

	public void setX1(double x) {
		this.beginPoint.setX(x);
		super.setX1((int)Math.round(x));
	}

	public void setY1(double y) {
		this.beginPoint.setY(y);
		super.setY1((int)Math.round(y));
	}

	public void setX2(double x) {
		this.endPoint.setX(x);
		super.setX2((int)Math.round(x));	
	}

	public void setY2(double y) {
		this.endPoint.setY(y);
		super.setY2((int)Math.round(y));
	}
	
	
	public Splain getParent() {
		return splain;
	}

	public void setParent(Splain parent) {
		this.splain = parent;
	}


	private class MouseActions implements MouseUpHandler,MouseOutHandler,MouseOverHandler, MouseDownHandler{

		@Override
		public void onMouseDown(MouseDownEvent event) {
			polygenObjectListener.onMouseDown(event, splain);
		}

		@Override
		public void onMouseUp(MouseUpEvent event) {
			polygenObjectListener.onMouseUp(event, splain);
		}

		@Override
		public void onMouseOver(MouseOverEvent event) {
			polygenObjectListener.onMouseOver(event, splain);
		}

		@Override
		public void onMouseOut(MouseOutEvent event) {
			polygenObjectListener.onMouseOut(event, splain);
		}
		
	}
	
}
